package ws.very.util.mapdb.akka.wraper

import scala.concurrent.duration._
import java.nio.charset.Charset
import ws.very.util.akka.io.FileDesc
import ws.very.util.akka.io.TmpFileDesc
trait Cache

object Cache {
  trait Sizeable {
    def size: I
  }
  val defaultSize = 1024 * 32
  case class HashTable(size: I = defaultSize) extends Cache with Sizeable
  case class HardRef(size: I = defaultSize) extends Cache with Sizeable
  case class WeekRef() extends Cache
  case class SoftRef() extends Cache
  case class LRU(size: I = defaultSize) extends Cache with Sizeable
  def default = HashTable()
}

object Compression extends Enumeration {
  val lzf = Value
}

object Encryption extends Enumeration {
  val xtea = Value
  def apply(pwd: S): Encryption = Encryption(pwd.getBytes(Charset.forName("UTF8")))
}
case class Encryption(pwd: Array[Byte], typ: Encryption.Value = Encryption.xtea)

trait Store {
  def readOnly: B
  def asyncWrite: O[Store.AsyncWrite]
}

object Store {

  val defaultFreeSpaceReclaimQ = 5
  case class AsyncWrite(flushDelay: Duration = 100 milli, queueSize: I = 32000)
  case class Heap(asyncWrite: O[AsyncWrite] = None) extends Store {
    def readOnly = false
  }

  trait File extends Store {
    def file: FileDesc

    def compression: O[Compression.Value]
    def encryption: O[Encryption]
    def deleteFilesAfterClose: B
    def commitFileSync: B
    def checksum: B
    def transaction: B
  }
  trait Volume extends File {
    def sizeLimit: O[L]
    def volume: Volume.Value
    def freeSpaceReclaimQ: I
  }
  case class Append(
    file: FileDesc = TmpFileDesc(), encryption: O[Encryption] = None, compression: O[Compression.Value] = None, readOnly: B = false,
    transaction: B = true, deleteFilesAfterClose: B = false, commitFileSync: B = true,
    checksum: B = false, asyncWrite: O[AsyncWrite] = None) extends File

  case class WAL(
    file: FileDesc = TmpFileDesc(), encryption: O[Encryption] = None, compression: O[Compression.Value] = None, readOnly: B = false,
    deleteFilesAfterClose: B = false, commitFileSync: B = true,
    checksum: B = false, sizeLimit: O[L] = None, volume: Volume.Value = Volume.default,
    asyncWrite: O[AsyncWrite] = None, freeSpaceReclaimQ: I = defaultFreeSpaceReclaimQ) extends File with Volume {
    def transaction: B = true
  }
  case class Direct(
    file: FileDesc = TmpFileDesc(), encryption: O[Encryption] = None, compression: O[Compression.Value] = None, readOnly: B = false,
    deleteFilesAfterClose: B = false, commitFileSync: B = true,
    checksum: B = false, sizeLimit: O[L] = None, volume: Volume.Value = Volume.default,
    asyncWrite: O[AsyncWrite] = None, freeSpaceReclaimQ: I = defaultFreeSpaceReclaimQ) extends File with Volume {
    def transaction: B = false
  }
}

object Volume extends Enumeration {
  val raf, mmapfPartial, mmapfIfSupported, mmapf, byteBuffer, directByteBuffer = Value
  def default = raf
}
case class MakeEngine(store: Store = Store.Direct(), /*fullTx时开启*/ snapshot: B = false, fullTx: B = false, closeOnJvmShutdown: B = true, cache: O[Cache] = Some(Cache.default))

case class DbMaker(makeEngine: MakeEngine = MakeEngine(),
                   /*停用一些map 原子的自默认*/
                   strictDBGet: B = false) 
//case class DbNameTo(maker: DbMaker, name: S)                    

  //FIXME:TxDBMarker
